package cn.patient.pp.framework.excel.core.listener;

import cn.patient.pp.framework.common.exception.ServiceException;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author liqingsong
 * @date 2025/4/21
 * @Description，这里是导入execl模板的检查监听器，如果不符合规定模板则不准导入
 */
public class TemplateCheckListener<T> extends AnalysisEventListener<T> {

    private final List<String> expectedHeaders;

    public TemplateCheckListener(List<String> expectedHeaders) {
        this.expectedHeaders = expectedHeaders;
    }

    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // 获取当前行号，判断是否是第二行（即表头行）
//        if (context.getCurrentRowNum() == 1) {
//            // 如果是第一行（表头），不做校验，直接返回
//            return;
//        }
        // 第二行及其之后的数据进行校验
        List<String> actualHeaders = new ArrayList<>();
        //这边控制列
        for (int i = 0; i < headMap.size(); i++) {
            actualHeaders.add(headMap.get(i));
        }

        StringBuilder errorBuilder = new StringBuilder();
        int expectedSize = expectedHeaders.size();
        int actualSize = actualHeaders.size();

        // 同时遍历 expected 和 actual 列表
        int maxSize = Math.max(expectedSize, actualSize);
        for (int i = 0; i < maxSize; i++) {
            String expected = i < expectedSize ? expectedHeaders.get(i) : null;
            String actual = i < actualSize ? actualHeaders.get(i) : null;

            if (expected == null) {
                errorBuilder.append(String.format("第 %d 列为多余字段：“%s”\n", i + 1, actual));
            } else if (actual == null) {
                errorBuilder.append(String.format("第 %d 列缺失字段，应为：“%s”\n", i + 1, expected));
            } else if (!expected.equals(actual)) {
                errorBuilder.append(String.format("第 %d 列字段错误，应为：“%s”，实际为：“%s”\n", i + 1, expected, actual));
            }
        }

        // 有错误就抛出异常
        if (errorBuilder.length() > 0) {
            throw new ServiceException(500, "模板校验失败：\n" + errorBuilder.toString());
        }
    }

    @Override
    public void invoke(T data, AnalysisContext context) {
        // 你可以加行校验逻辑在这里（可选）
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 可选处理逻辑
    }
}
